
#ifndef RTHTTPPROXYMANAGER_H
#define RTHTTPPROXYMANAGER_H

#include "RtHttpProxyInfoGetter.h"
#include "RtObserver.h"
#include "RtHttpAuthInfoGetter.h"
#include "RtMutex.h"
#include <vector>

class /*RT_API_EXPORT*/ CRtHttpProxyManager : public IRtObserver
{
public:
	static CRtHttpProxyManager* Instance();
	
	IRtHttpProxyInfoGetter::NextReturn GetProxyInfo(
		const CRtString &aHost, 
		WORD aPort, 
		CRtHttpProxyInfo* &aPi);
	
	// return RT_OK: rewind from beginning.
	// return RT_ERROR_FOUND: find and advance.
	RtResult ClearCacheProxy(const CRtString &aHost, WORD aPort);

	BOOL CreateProxyInfo(
		const CRtString &aProxy, 
		CRtHttpProxyInfo::PROXY_TYPE aType, 
		CRtHttpProxyInfo *&aPi);

	// interface IRtObserver
	virtual void OnObserve(LPCSTR aTopic, LPVOID aData = NULL);

	RtResult AddObserver(IRtObserver *aObserver);
	RtResult RemoveObserver(IRtObserver *aObserver);

	IRtHttpAuthInfoGetter::GETTER_RESULT GetAuthInfoFromDialog(
		const CRtString &aChallenge, 
		CRtHttpProxyInfo *aPi, 
		IRtObserver *aObserver);

	IRtHttpAuthInfoGetter* GetHttpAuthInfoGetter();

	CRtString GetSchemeFromChallenge(const CRtString &aChallenge);

	BOOL IsBrowerProxySet();

private:
	CRtHttpProxyManager();
	virtual ~CRtHttpProxyManager();

	BOOL InitGetterArray();
	// 0 for wpad, 1 for autoconfig, 2 for manual
	enum { PROXY_TYPE_NUM = 3 };
	CRtString m_strProxyArray[PROXY_TYPE_NUM];
	CRtString m_strBypass;
	CRtAutoPtr<IRtHttpProxyInfoGetter> m_GetterArray[PROXY_TYPE_NUM];
	BOOL m_bIsDeadArray[PROXY_TYPE_NUM];

	typedef CRtMutexThreadRecursive MutexType;
	MutexType m_Mutex;

	typedef std::vector<CRtHttpProxyInfo *> ProxyInfoArrayType;
	ProxyInfoArrayType m_ProxyInfoCaches;
	ProxyInfoArrayType::iterator m_itProxyInfoCached;

	IRtHttpProxySetting::BrowseType m_BrowserType;
	IRtHttpProxySetting *m_pHttpProxySetting;
	typedef std::vector<IRtObserver *> ObserversType;
	ObserversType m_Observers;

	IRtHttpAuthInfoGetter *m_pHttpAuthInfoGetter;

	friend class CRtSingletonT<CRtHttpProxyManager>;
};

#endif // !RTHTTPPROXYMANAGER_H
